/**
 * @brief	软件模拟 PWM
 * @details	通过普通GPIO,模拟PWM
 * @file    Bsp_Port\bsp_soft_PWM.c
 * @par History:
 *	V1.0: 蔡正祥, 2024-01-09, 新建之初\n
 */
#include "bsp_soft_PWM.h"
#include "stdlib.h"
#include "bsp_Timer.h"

soft_PWM_t *soft_PWM_Buff[SOFT_PWM_MAX_NUM] = {0};
// 函数声明
void bsp_softPwm_Obj_Handle(soft_PWM_t *obj);

/*  @brief  软PWM 对象定时计数
    @return 无
    @property 放在1ms定时器中
*/
void bsp_softPwm_IRQHandler(void)
{
    for (uint8_t counti = 0; counti < SOFT_PWM_MAX_NUM; counti++)
    {
        if (soft_PWM_Buff[counti] == NULL)
        {
            break;
        }

        if (soft_PWM_Buff[counti]->sp_State == sp_RUN)
        {
            soft_PWM_Buff[counti]->sp_Mcu.sp_nowTim++;
        }
    }
}
/*  @brief  软PWM 主函数处理
    @return 无
    @property 放在main主循环中
*/
void bsp_soft_PWM_All_Handle(void)
{
    static uint8_t soft_PWM_Index = 0;

    for (uint8_t counti = 0; counti < 3; counti++)
    {
        if (soft_PWM_Buff[soft_PWM_Index] != NULL)
        {
            if (soft_PWM_Buff[soft_PWM_Index]->sp_State == sp_RUN)
            {
                bsp_softPwm_Obj_Handle(soft_PWM_Buff[soft_PWM_Index]);
                soft_PWM_Index++;
                return;
            }
            else
            {
                soft_PWM_Index++;
            }
        }
        else
        {
            soft_PWM_Index = 0;
        }
    }
}

/*  @brief  软PWM调试函数
    @param  变量1
            注释
    @param  变量2
            注释L
    @return 无
    @property 无
*/
void bsp_softPwm_Debug(void)
{
    soft_PWM_t myPwm;
    bsp_softPwm_Obj_New(&myPwm, PWM_LED_GPIO, 1000, 50, sp_RUN);
    while (1)
    {
        bsp_soft_PWM_All_Handle();
    }
}

/*  @brief  新建一个 软PWM 对象
    @param  obj
            软PWM 对象
    @param  *gpio、pin
            GPIO引脚
    @param  cycle
            周期(>10ms)
    @param  pulse
            占空比%
    @param  state
            状态:     sp_STOP, // 关闭  sp_RUN,  // 打开
    @return 无
    @property 无
*/
void bsp_softPwm_Obj_New(soft_PWM_t *obj, GPIO_TypeDef *gpio, uint32_t pin, uint32_t cycle, uint8_t pulse, softPwm state)
{
    // soft_PWM_t *new_obj = malloc(sizeof(soft_PWM_t));

    obj->sp_Hz = (1.0 / cycle) * 1000.0; // 频率
    obj->sp_Cycle_ms = cycle;            // 周期
    obj->sp_Pulse = pulse;               // 占空比
    obj->sp_State = state;               // 状态

    obj->sp_Mcu.sp_GPIOx = gpio;
    obj->sp_Mcu.sp_Pin = pin;
    BSP_SET_LOW(obj->sp_Mcu.sp_GPIOx, obj->sp_Mcu.sp_Pin);

    for (uint8_t counti = 0; counti < SOFT_PWM_MAX_NUM; counti++)
    {
        if (soft_PWM_Buff[counti] == NULL)
        {
            soft_PWM_Buff[counti] = obj;
            return;
        }
    }
}
/*  @brief  软PWM 单个对象处理函数
    @param  *obj
            对象名
    @return 无
    @property 无
*/
void bsp_softPwm_Obj_Handle(soft_PWM_t *obj)
{
    uint32_t nowTim = obj->sp_Mcu.sp_nowTim;
    uint32_t agoTim = obj->sp_Mcu.sp_agoTim;
    uint32_t gapTim = nowTim - agoTim; // 差值

    if (obj->sp_Pulse == 0)
    {
        BSP_SET_LOW(obj->sp_Mcu.sp_GPIOx, obj->sp_Mcu.sp_Pin); // 电平拉低;
        return;
    }
    else if (obj->sp_Pulse == 100)
    {
        BSP_SET_HIGH(obj->sp_Mcu.sp_GPIOx, obj->sp_Mcu.sp_Pin); // 电平拉高
        return;
    }

    uint32_t pulseTim = obj->sp_Cycle_ms * obj->sp_Pulse / 100.0; // 占空比 时间

    if (gapTim >= pulseTim && BSP_GET_READ(obj->sp_Mcu.sp_GPIOx, obj->sp_Mcu.sp_Pin) == 1)
    {
        BSP_SET_LOW(obj->sp_Mcu.sp_GPIOx, obj->sp_Mcu.sp_Pin); // 电平拉低;
    }

    if (gapTim >= obj->sp_Cycle_ms)
    {
        BSP_SET_HIGH(obj->sp_Mcu.sp_GPIOx, obj->sp_Mcu.sp_Pin); // 电平拉高
        obj->sp_Mcu.sp_agoTim = nowTim;                         // 重新开始;
    }
}
/*  @brief  软PWM 设置占空比
    @param  *obj
            软PWM 对象
    @param  pulse
            占空比
    @return 无
    @property 无
*/
void bsp_softPwm_Set_Pulse(soft_PWM_t *obj, uint8_t pulse)
{
    obj->sp_Pulse = pulse;
}
/*  @brief  软PWM 设置周期
    @param  *obj
            软PWM 对象
    @param  cycle
            周期
    @return 无
    @property 无
*/
void bsp_softPwm_Set_Cycle(soft_PWM_t *obj, uint8_t cycle)
{
    obj->sp_Cycle_ms = cycle;
}
/*  @brief  软PWM 运行
    @param  *obj
            软PWM 对象
    @return 无
    @property 无
*/
void bsp_softPwm_RUN(soft_PWM_t *obj)
{
    BSP_SET_HIGH(obj->sp_Mcu.sp_GPIOx, obj->sp_Mcu.sp_Pin);
    obj->sp_State = sp_RUN;
}
/*  @brief  软PWM 停止
    @param  *obj
            软PWM 对象
    @return 无
    @property 无
*/
void bsp_softPwm_STOP(soft_PWM_t *obj)
{
    BSP_SET_LOW(obj->sp_Mcu.sp_GPIOx, obj->sp_Mcu.sp_Pin);
    obj->sp_State = sp_STOP;
}

/*  @brief  获取 软PWM 运行状态
    @param  *obj
            软PWM 对象
    @return sp_STOP sp_RUN
    @property 无
*/
softPwm bsp_Get_softPwm_State(soft_PWM_t *obj)
{
    return (obj->sp_State);
}
